package com.squid.search.service.index;


import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.mapping.Property;
import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
import co.elastic.clients.elasticsearch.indices.*;
import co.elastic.clients.util.ObjectBuilder;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.HashMap;
import java.util.function.Function;

/**
 * @author jh
 * date 2023/8/9 13:30
 */
@Service
@Slf4j
public class EsIndexServiceImpl implements EsIndexService {
    @Resource
    ElasticsearchClient elasticsearchClient;

    public void createIndex(String indexName) {
        try {
            CreateIndexResponse response = elasticsearchClient.indices().create(c -> c.index(indexName));
            if (!response.acknowledged()) {
                throw new RuntimeException("创建索引失败");
            }
        } catch (IOException e) {
            log.error("创建索引失败", e);
            throw new RuntimeException(e);
        }
    }

    @Override
    public void createIndex(String name, Function<IndexSettings.Builder, ObjectBuilder<IndexSettings>> settingFn
            , Function<TypeMapping.Builder
            , ObjectBuilder<TypeMapping>> mappingFn) {
        try {
            CreateIndexResponse response = elasticsearchClient
                    .indices()
                    .create(c -> c
                            .index(name)
                            .settings(settingFn)
                            .mappings(mappingFn)
                    );
            if (!response.acknowledged()) {
                throw new RuntimeException("创建索引失败");
            }
        } catch (IOException e) {
            log.error("创建索引失败", e);
            throw new RuntimeException(e);
        }
    }

    @Override
    public void deleteIndex(String name) {
        try {
            DeleteIndexResponse response = elasticsearchClient.indices().delete(c -> c.index(name));
            if (!response.acknowledged()) {
                throw new RuntimeException("删除索引失败");
            }
        } catch (IOException e) {
            log.error("删除索引失败", e);
            throw new RuntimeException(e);
        }
    }

    @Override
    public void updateIndexProperty(String name, HashMap<String, Property> propertyMap) {
        try {
            PutMappingResponse response = elasticsearchClient.indices()
                    .putMapping(typeMappingBuilder ->
                            typeMappingBuilder
                                    .index(name)
                                    .properties(propertyMap)
                    );
            if (!response.acknowledged()) {
                throw new RuntimeException("更新索引失败");
            }
        } catch (IOException e) {
            log.error("更新索引失败", e);
            throw new RuntimeException(e);
        }

    }

    @Override
    public GetIndexResponse getIndexList() {
        //使用 * 或者 _all都可以
        try {
            GetIndexResponse response = elasticsearchClient.indices().get(builder -> builder.index("_all"));
            log.info("getIndexList方法，response.result()={}", response.result().toString());
            return response;
        } catch (IOException e) {
            log.error("获取索引失败", e);
            throw new RuntimeException(e);
        }
    }

    @Override
    public GetIndexResponse getIndexDetail(String name) {
        try {
            GetIndexResponse response = elasticsearchClient.indices().get(builder -> builder.index(name));
            log.info("getIndexDetail方法，response.result()={}", response.result().toString());
            return response;
        } catch (IOException e) {
            log.error("获取索引失败", e);
            throw new RuntimeException(e);
        }
    }

    @Override
    public Boolean indexExists(String name) {
        try {
            return elasticsearchClient.indices().exists(x -> x.index(name)).value();
        } catch (IOException e) {
            log.error("检查索引是否存在失败", e);
            throw new RuntimeException(e);
        }
    }
}